package indi.cyh.fastservice.base;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import indi.cyh.fastservice.base.entity.db.OrderByCondition;
import indi.cyh.fastservice.base.entity.db.QueryCondition;
import indi.cyh.fastservice.base.request.*;
import indi.cyh.jdbctool.core.DataSourceFactory;
import indi.cyh.jdbctool.core.JdbcDataBase;
import indi.cyh.jdbctool.tool.EntityTool;
import indi.cyh.jdbctool.tool.StringTool;
import lombok.SneakyThrows;


import java.lang.reflect.ParameterizedType;
import java.util.*;

/**
 * @Description TODO
 * @Author CYH
 * @Date 2021/7/22 10:35
 **/
public abstract class BaseBizImpl<T> implements BaseBiz {

    JdbcDataBase db = DataSourceFactory.getJdbcDataBase();

    Class<T> entityType = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];

    @Override
    public boolean save(BaseSaveRequest request) throws Exception {
        String transactionId = db.beginTransaction();
        try {
            JSONArray arr = JSONObject.parseArray(request.getJson());
            for (int i = 0; i < arr.size(); i++) {
                T t = (T) arr.getObject(i, entityType);
                String primaryFieldValue = EntityTool.getPrimaryFeldValue(entityType, t);
                if (!StringTool.isEmpty(primaryFieldValue)) {
                    db.updateById(entityType, t);
                } else {
                    db.insert(entityType, t, false);
                }
            }
            db.commitTransaction(transactionId);
            return true;
        } catch (Exception e) {
            db.rollbackTransaction(transactionId);
            return false;
        }
    }

    @Override
    public boolean delete(BaseDeleteRequest request) throws Exception {
        if (StringTool.isEmpty(request.getIds())) {
            throw new Exception("主键不能为空!");
        }
        db.deleteByIds(entityType, Arrays.asList(request.getIds().split(",")));
        return true;
    }

    @Override
    public Object queryPageData(BaseQueryPageDataRequest request) throws Exception {
        //sql中表和字段的名称
        List<Object> sqlWord = new ArrayList<>();
        //查询参数的值
        List<Object> valueList = new ArrayList<>();
        String sql = "select  *  from  %s where 1=1 \n";
        sqlWord.add(EntityTool.getTableName(entityType));
        //过滤
        sql = queryListDataFilter(sql, sqlWord, valueList, request.getCondition());
        //排序
        sql = String.format(queryListSortSql(sql, sqlWord, request.getSort()), sqlWord.toArray());
        return db.queryPageData(sql, request.getPage(), request.getRow(), true, valueList.toArray());
    }

    /**
     * 添加排序条件
     *
     * @param sql
     * @param sqlWord
     * @param sortJson
     * @return java.lang.String
     * @author CYH
     * @date 2021/8/31 16:57
     **/
    private String queryListSortSql(String sql, List<Object> sqlWord, String sortJson) throws Exception {
        if (StringTool.isEmpty(sortJson)) {
            return sql;
        }
        sql += " order by ";
        JSONArray sortArr = JSONArray.parseArray(sortJson);
        for (int i = 0; i < sortArr.size(); i++) {
            sql = addSortSql(sql, sqlWord, sortArr.getObject(i, OrderByCondition.class), i != 0);
        }
        return sql;
    }

    /**
     * 添加单个sql排序条件
     *
     * @param sql
     * @param sqlWord
     * @param condition
     * @return java.lang.String
     * @author CYH
     * @date 2021/8/31 16:56
     **/
    private static String addSortSql(String sql, List<Object> sqlWord, OrderByCondition condition, boolean addComma) throws Exception {
        if (addComma) {
            sql += ",%s %s";
        } else {
            sql += " %s %s";
        }
        String orderByType = "";
        switch (Enums.OrderType.valueOf(condition.getOrderByType())) {
            case DESC:
                orderByType = "desc";
                break;
            default:
                orderByType = "asc";
        }
        sqlWord.add(condition.getColumonName());
        sqlWord.add(orderByType);
        return sql;
    }

    /**
     * 添加查询条件
     *
     * @param sql
     * @param sqlWord
     * @param valueList
     * @param conditionJosnArr
     * @return java.lang.String
     * @author CYH
     * @date 2021/8/31 16:57
     **/
    private String queryListDataFilter(String sql, List<Object> sqlWord, List<Object> valueList, String conditionJosnArr) throws Exception {
        if (StringTool.isEmpty(conditionJosnArr)) {
            return sql;
        }
        JSONArray conditionArr = JSON.parseArray(conditionJosnArr);
        if (conditionArr != null && conditionArr.size() != 0) {
            for (int i = 0; i < conditionArr.size(); i++) {
                QueryCondition condition = conditionArr.getObject(i, QueryCondition.class);
                sql = addConditionSql(sql, sqlWord, condition, valueList);
            }
        }
        return sql;
    }

    /**
     * 添加单个查询条件sql
     *
     * @param sql
     * @param sqlWord
     * @param condition
     * @param valueList
     * @return java.lang.String
     * @author CYH
     * @date 2021/8/31 16:59
     **/
    private static String addConditionSql(String sql, List<Object> sqlWord, QueryCondition condition, List<Object> valueList) throws Exception {
        if (StringTool.isEmpty(condition.getValue())) {
            return sql;
        }
        switch (Enums.CompareType.valueOf(condition.getCompareType())) {
            case EQUALS:
                sql += " and  %s = %s \n";
                break;
            case LIKE:
                sql += " and  %s like  '%'||%s||'%'";
                break;
        }
        sqlWord.add(condition.getColumonName());
        sqlWord.add(valueConversionSql(valueList, condition.getValueConversionType(), condition.getValue()));
        return sql;
    }

    private static Object valueConversionSql(List<Object> valueList, int valueConversionType, String value) throws Exception {
        String res = "";
        switch (Enums.ConversionType.valueOf(valueConversionType)) {
            case SOURCE:
                res = "?";
                valueList.add(value);
                break;
            case TIMESTAMP:
        }
        return res;
    }

    @SneakyThrows
    @Override
    public Object queryOne(BaseQueryOneRequest request) throws Exception {
        //sql中表和字段的名称
        List<Object> sqlWord = new ArrayList<>();
        //查询参数的值
        List<Object> valueList = new ArrayList<>();
        String sql = "select  *  from  %s where 1=1 \n";
        sqlWord.add(EntityTool.getTableName(entityType));
        if (!StringTool.isEmpty(request.getCondition())) {
            sql = queryListDataFilter(sql, sqlWord, valueList, request.getCondition());
        }
        sql = String.format(sql, sqlWord.toArray());
        List<Map<String, Object>> resList = db.queryListMap(sql, valueList.toArray());
        if (resList != null && resList.size() != 0) {
            return resList.get(0);
        } else {
            return new HashMap<>();
        }
    }

    @Override
    public Object queryList(BaseQueryListRequest request) throws Exception {
        //sql中表和字段的名称
        List<Object> sqlWord = new ArrayList<>();
        //查询参数的值
        List<Object> valueList = new ArrayList<>();
        String sql = "select  *  from  %s where 1=1 \n";
        sqlWord.add(EntityTool.getTableName(entityType));
        if (!StringTool.isEmpty(request.getCondition())) {
            sql = queryListDataFilter(sql, sqlWord, valueList, request.getCondition());
        }
        sql = queryListSortSql(sql, sqlWord, request.getSort());
        sql = String.format(sql, sqlWord.toArray());
        return db.queryListMap(sql, valueList.toArray());
    }
}
